package com.cb.domain.service.order.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;
import org.tempuri.ServiceSoap;

import webservices.alipaydirect.services.AlipayService;
import webservices.alipaydirect.util.UtilDate;
import webservices.mobile.MoblieUtil;

import com.cb.common.enumType.OrderStatus;
import com.cb.common.enumType.PassengerType;
import com.cb.common.map.BOrderCommon;
import com.cb.common.util.BeanUtil;
import com.cb.common.webService.ClientService;
import com.cb.controller.front.order.XmlConverUtil;
import com.cb.core.service.impl.GenericManagerImpl;
import com.cb.core.webapp.paging.PagingBean;
import com.cb.domain.dao.order.BOrderDAO;
import com.cb.domain.dao.order.PassengerDAO;
import com.cb.domain.model.order.BOrder;
import com.cb.domain.model.order.Flight;
import com.cb.domain.model.order.Insurance;
import com.cb.domain.model.order.Passenger;
import com.cb.domain.model.order.PassengerDto;
import com.cb.domain.service.order.BOrderManager;
import com.cb.domain.service.order.OrderLogManager;

@Transactional
@Service(value="bOrderManager")
public class BOrderManagerImpl extends GenericManagerImpl<BOrder, Long>
		implements BOrderManager {
	@Autowired
	private PassengerDAO passengerDAO;
	@Autowired
	private BOrderDAO bOrderDAO;
	@Autowired
	private OrderLogManager orderLogManager;

	@Autowired
	public BOrderManagerImpl(BOrderDAO bOrderDAO) {
		super(bOrderDAO);
	}

	/**
	 * {@inheritDoc}
	 */
	public List<BOrder> getByVo(BOrder vo, PagingBean pb) {
		return ((BOrderDAO) genericDAO).getByVo(vo, pb);
	}

	public void saveOrderAndLog(BOrder vo, String sendMsg) {

//		int status = MoblieUtil.sendSms(vo.getContactMob(), sendMsg);
//		if (status == 0) {
			bOrderDAO.save(vo);
			String action = "新建订单" + vo.getOrderNo() + "成功";
			orderLogManager.saveLog(action, "1", vo.getId().toString());
//		}
	}

	public String cancleHybx() {
		ClientService<webservices.hybc.ServiceSoap> clientService = new ClientService<webservices.hybc.ServiceSoap>();
		webservices.hybc.ServiceSoap service = clientService.getClient(
				"hybx.path", webservices.hybc.ServiceSoap.class);

		String result = service.hyCBService("TB2022060270617", "20120604",
				"dmsun", "9871d");
		return result;
	}

	public static void main(String[] args) {
		BOrderManagerImpl bOrderManagerImpl = new BOrderManagerImpl(null);
		// String result=bOrderManagerImpl.saveHybx();//新增
		String result = bOrderManagerImpl.cancleHybx();// 取消

		System.out.println(result);
	}

	@Override
	public boolean saveOrderByHttpClient() {
		// TODO Auto-generated method stub
		boolean res = false;
		HttpClient client = new HttpClient();
		client.getHostConfiguration().setProxy("10.123.74.137", 808);
		PostMethod method = new PostMethod(
				"http://tts.mtrip.net/tts/interface/new/orderexport?type=all&status=2&user=mysl&pass=mysl");
		try {
			int status = client.executeMethod(method);
			InputStream is = method.getResponseBodyAsStream();
			int i = -1;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while ((i = is.read()) != -1) {
				baos.write(i);
			}
			if (StringUtils.isNotEmpty(baos.toString())) {
				Document doc = XmlConverUtil.str2Xml(baos.toString());
				if (null != doc) {
					Element root = doc.getRootElement();
					List nodes = root.elements();
					Element firstNode = (Element) nodes.get(0);
					String elementStatus = firstNode.attributeValue("status");
					if (StringUtils.isNotEmpty(elementStatus)) {
						if (!elementStatus.equals("ok")) {
							Element msgElememt = firstNode.element("msg");
							StringBuilder sb = new StringBuilder();
							sb.append("result status:" + elementStatus);
							if (null != msgElememt) {
								sb.append(msgElememt.getText());
							}
							log.warn(sb.toString());
							res = false;
						} else {
							XmlConverUtil xmlUtil = new XmlConverUtil();
							List<BOrder> orderList = (List<BOrder>) xmlUtil
									.xmltoList(baos.toString());
							if (null != orderList && orderList.size() > 0) {
								for (BOrder order : orderList) {
									bOrderDAO.save(order);
								}
								res = true;
							} else {
								log.warn("XML没有数据");
								res = false;
							}
						}
					}
				}

			} else {
				log.warn("接口没有返回内容");
				res = false;
			}

		} catch (HttpException e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage(), e);
			res = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage(), e);
			res = false;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			res = false;
		} finally {
			method.releaseConnection();
		}
		return res;
	}
	
	/**
	 * 拆分订单 
	 * @return
	 */
	public Boolean newSplitBOrder(BOrder order,String [] passengerIds,Long status){

		if (null!=order&&passengerIds.length>0) {
			if (null != order) {
				BOrder newCreateOrder = copyOrder(order);;
				BOrder moveOrder = copyOrder(order);
				List<Passenger> newPas=new ArrayList<Passenger>();
				List<Passenger> movePas=new ArrayList<Passenger>();
				Set<Passenger> passengers= order.getPassengers();
				
				//新类型订单金额
				Double newPasInsuranceStatistics=0d;
				Long newAllPrice=0l;
				
				//拆分后新订单金额
				Double movePasInsuranceStatistics=0d;
				Long moveAllPrice=0l;
				for (Iterator iterator = passengers.iterator(); iterator.hasNext();) {
					Passenger passenger = (Passenger) iterator.next();
					Boolean isMatch=false;
					for (int i = 0; i < passengerIds.length; i++) {
						if(passenger.getId().equals(Long.valueOf(passengerIds[i]))){
							newPas.add(passenger);
							newPasInsuranceStatistics+=Double.valueOf(passenger.getBxPrice());
							newAllPrice+=passenger.getTotalPrice().longValue();
							isMatch=true;
							break;
						}
					}
					if(!isMatch){
						movePas.add(passenger);
						movePasInsuranceStatistics+=Double.valueOf(passenger.getBxPrice());
						moveAllPrice+=passenger.getTotalPrice().longValue();
					}
				}
				//需要更改类型的订单需要减去快递费
				if(newCreateOrder.getXcdPrice()!=null){
					newCreateOrder.setAllPrice(newCreateOrder.getAllPrice()-newCreateOrder.getXcdPrice());
				}
				if(newPas.size()>0){
				
				//新订单类型价格更改
				newCreateOrder.setStatus(status);
				newCreateOrder.setCreateTime(new Date());
				newCreateOrder.setAllPrice(newAllPrice);
				newCreateOrder.setViewPrice(newAllPrice);
				newCreateOrder.setInsuranceStatistics(newPasInsuranceStatistics);
				newCreateOrder.setOrderNo("m"+UtilDate.getOrderNum());
				//要操作类型的订单
				reBuildOrder(newCreateOrder, newPas);
				}
				
				//拆分后新订单价格更改
				if(movePas.size()>0){
					moveOrder.setCreateTime(new Date());
					if(order.getNoPay()>0){
						moveOrder.setNoPay(moveAllPrice);
						newCreateOrder.setNoPay(newAllPrice);
					}
					moveOrder.setAllPrice(moveAllPrice);
					moveOrder.setViewPrice(moveAllPrice);
					moveOrder.setInsuranceStatistics(movePasInsuranceStatistics);
					moveOrder.setOrderNo("m"+UtilDate.getOrderNum());
					//原订单拆分出来的新订单
					reBuildOrder(moveOrder, movePas);
				}
				//取消原订单
				order.setStatus(BOrderCommon.getOrderStatusMap().get(OrderStatus.CANCEL_OK));
				bOrderDAO.update(order);
			}
		}
		return true;
	}

	@Override
	public String splitBOrder(BOrder order) {
		// TODO Auto-generated method stub
		String res = "";
		Set<Passenger> passList = order.getPassengers();
		if (passList.size() > 1) {
			long childValue = order.getChildPrintPrice();
			long childFaceValue = order.getChildFaceValue();
			long adValue = order.getPrice() - childValue;
			long adFaceValue = order.getViewPrice() - childFaceValue;
			int chdCount = 0;
			int adCount = 0;
			for (Passenger pass : passList) {
				String type = pass.getAgeType();
				if (type == PassengerType.AD.toString()) {
					adCount++;
				} else {
					chdCount++;
				}
			}
			long perChdSaleValue = 0;
			long perAdSaleValue = 0;
			long perChdFaceValue = 0;
			long perAdFaceValue = 0;
			if (adCount > 0) {
				perAdSaleValue = adValue / adCount;
				perAdFaceValue = adFaceValue / adCount;
			}
			if (chdCount > 0) {
				perChdSaleValue = childValue / chdCount;
				perChdFaceValue = childFaceValue / chdCount;
			}
			for (Passenger pass : passList) {
				BOrder targetOrder = copyOrder(order);
				String type = pass.getAgeType();
				if (type == PassengerType.AD.toString()) {
					targetOrder.setChildFaceValue(Long.valueOf(0));
					targetOrder.setChildPrintPrice(Long.valueOf(0));
					targetOrder.setPrice(perAdSaleValue);
					targetOrder.setViewPrice(perAdFaceValue);
					if (null != targetOrder.getConstructionFee()) {
						pass.setConstructionFee(targetOrder
								.getConstructionFee().longValue());
					}
					if (null != targetOrder.getFuelTax()) {
						pass.setFuelTax(targetOrder.getFuelTax().longValue());
					}
				} else {
					targetOrder.setChildFaceValue(perChdSaleValue);
					targetOrder.setChildPrintPrice(perChdFaceValue);
					targetOrder.setPrice(perChdSaleValue);
					targetOrder.setViewPrice(perChdFaceValue);
					if (null != targetOrder.getFuelTax()) {
						pass.setFuelTax(targetOrder.getChildFuelTax()
								.longValue());
					}
				}
//				reBuildOrder(targetOrder, pass);
			}
			bOrderDAO.remove(order);
			res = "拆分成功";
		} else {
			res = "旅客数量有误,不能被拆分";
		}
		return res;
	}

	/**
	 * 根据每个旅客重新生成BORDER订单
	 * 
	 * @param order
	 * @param passenger
	 */
	private void reBuildOrder(BOrder order, List<Passenger> passengers) {
		Set<Passenger> passList = new HashSet<Passenger>();
		for (Passenger passenger : passengers) {
			Passenger newPassenger = new Passenger();
			try {
				Long pId = newPassenger.getId();
				newPassenger = (Passenger) BeanUtil.CopyBeanToBean(passenger,
						newPassenger);
				newPassenger.setbOrder(order);
				newPassenger.setInsurances(rebuildInsurance(
						newPassenger.getInsurances(), newPassenger));
				newPassenger.setId(pId);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			passList.add(newPassenger);
		}
		order.setPassengers(passList);
		Set<Flight> fList = rebuildFlight(order.getFlights(), order);
		order.setFlights(fList);
		bOrderDAO.save(order);
	}

	private Set<Insurance> rebuildInsurance(Set<Insurance> list,
			Passenger passenger) {
		Set<Insurance> newList = new HashSet<Insurance>();
		if (null != list && list.size() > 0) {
			for (Insurance temp : list) {
				Insurance insurance = new Insurance();
				Long fId = insurance.getId();
				try {
					insurance = (Insurance) BeanUtil.CopyBeanToBean(temp,
							insurance);
					insurance.setId(fId);
					insurance.setPassenger(passenger);
					newList.add(insurance);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		return newList;
	}

	private Set<Flight> rebuildFlight(Set<Flight> list, BOrder order) {
		Set<Flight> newList = new HashSet<Flight>();
		if (null != list && list.size() > 0) {
			for (Flight temp : list) {
				Flight flight = new Flight();
				Long fId = flight.getId();
				try {
					flight = (Flight) BeanUtil.CopyBeanToBean(temp, flight);
					flight.setId(fId);
					flight.setOrder(order);
					newList.add(flight);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		return newList;
	}

	/**
	 * 拷贝源ORDER属性到新的ORDER
	 * 
	 * @param source
	 * @param target
	 */
	private BOrder copyOrder(BOrder source) {
		BOrder target = new BOrder();
		Long id = target.getId();
		try {
			source.setInsuranceStatistics(0d);
			target = (BOrder) BeanUtil.CopyBeanToBean(source, target);
			target.setId(id);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return target;
	}

	@Override
	public String getCreateDirectPay(String out_trade_no, String subject,
			String body, String total_fee, String paymethod, String defaultbank) {

		// 扩展功能参数——防钓鱼//
		// 防钓鱼时间戳
		String anti_phishing_key = "";
		// 获取客户端的IP地址，建议：编写获取客户端IP地址的程序
		String exter_invoke_ip = "";
		// 注意：
		// 1.请慎重选择是否开启防钓鱼功能
		// 2.exter_invoke_ip、anti_phishing_key一旦被设置过，那么它们就会成为必填参数
		// 3.开启防钓鱼功能后，服务器、本机电脑必须支持远程XML解析，请配置好该环境。
		// 4.建议使用POST方式请求数据
		// 示例：
		// anti_phishing_key = AlipayService.query_timestamp(); //获取防钓鱼时间戳函数
		// exter_invoke_ip = "202.1.1.1";

		// 扩展功能参数——其他///

		// 自定义参数，可存放任何内容（除=、&等特殊字符外），不会显示在页面上
		String extra_common_param = "";
		// 默认买家支付宝账号
		String buyer_email = "";
		// 商品展示地址，要用http:// 格式的完整路径，不允许加?id=123这类自定义参数
		String show_url = "http://127.0.0.1:8090/tts/front/index.do";

		// 扩展功能参数——分润(若要使用，请按照注释要求的格式赋值)//

		// 提成类型，该值为固定值：10，不需要修改
		String royalty_type = "";
		// 提成信息集
		String royalty_parameters = "";
		// 注意：
		// 与需要结合商户网站自身情况动态获取每笔交易的各分润收款账号、各分润金额、各分润说明。最多只能设置10条
		// 各分润金额的总和须小于等于total_fee
		// 提成信息集格式为：收款方Email_1^金额1^备注1|收款方Email_2^金额2^备注2
		// 示例：
		// royalty_type = "10"
		// royalty_parameters = "111@126.com^0.01^分润备注一|222@126.com^0.01^分润备注二"

		// ////////////////////////////////////////////////////////////////////////////////

		// 把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("payment_type", "1");
		sParaTemp.put("out_trade_no", out_trade_no);
		sParaTemp.put("subject", subject);
		sParaTemp.put("body", body);
		sParaTemp.put("total_fee", total_fee);
		sParaTemp.put("show_url", show_url);
		sParaTemp.put("paymethod", paymethod);
		sParaTemp.put("defaultbank", defaultbank);
		sParaTemp.put("anti_phishing_key", anti_phishing_key);
		sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
		sParaTemp.put("extra_common_param", extra_common_param);
		sParaTemp.put("buyer_email", buyer_email);
		sParaTemp.put("royalty_type", royalty_type);
		sParaTemp.put("royalty_parameters", royalty_parameters);

		// 构造函数，生成请求URL
		String sHtmlText = AlipayService.create_direct_pay_by_user(sParaTemp);
		return sHtmlText;
	}

	@Override
	public List<BOrder> getbOrderByTime(String beginTime, String endTime,
			PagingBean pageBean) {
		return bOrderDAO.getbOrderByTime(beginTime, endTime, pageBean);
	}

	@Override
	public Integer getOrderCountByType(String type) {
		Integer count = 0;
		String hql = "select count(*) from BOrder b where b.status=" + type;
		Long countValue = genericDAO.getCount(hql);
		count = countValue.intValue();
		return count;
	}

	@Override
	public BOrder findOrderByNo(String orderNo) {
		return bOrderDAO.findOrderByNo(orderNo);
	}

	@Override
	public Boolean xePnr(String pnr, String identity) {

		String requests = "<?xml version=\"1.0\"?><ABE_XEPNR_1_1><PNR>" + pnr
				+ "</PNR></ABE_XEPNR_1_1>";

		ClientService<ServiceSoap> clientService = new ClientService<ServiceSoap>();
		ServiceSoap service = clientService.getClient("abeService.path",
				ServiceSoap.class);
		String result = service.abeSubmit(identity, requests, "");
		Boolean isSucess = false;
		if (StringUtils.isBlank(result)) {
			isSucess = true;
		}
		return isSucess;
	}

	public List<PassengerDto> passenger2dto(Set<Passenger> passengers) {
		List<PassengerDto> allList = new ArrayList<PassengerDto>();

		PassengerDto ni = new PassengerDto();
		PassengerDto nip = new PassengerDto();
		PassengerDto chd = new PassengerDto();

		for (Passenger passenger : passengers) {
			if (passenger.getAgeType().equalsIgnoreCase("NI")) {
				if(passenger.getInsuranceCount()>0){
					nip=addPassengerDtoPrice(nip ,passenger);
					nip.setPassengerType("NIP");
				}else{
					ni=addPassengerDtoPrice(ni ,passenger);
					ni.setPassengerType("NI");
				}
			} else if (passenger.getAgeType().equalsIgnoreCase("CHD")) {
				chd=addPassengerDtoPrice(chd ,passenger);
				chd.setPassengerType("CHD");
			}
		}
		if (StringUtils.isNotBlank(ni.getPassengerType())) {
			allList.add(ni);
		}
		if (StringUtils.isNotBlank(nip.getPassengerType())) {
			allList.add(nip);
		}
		if (StringUtils.isNotBlank(chd.getPassengerType())) {
			allList.add(chd);
		}

		return allList;
	}
	
	private PassengerDto addPassengerDtoPrice(PassengerDto passengerDto,Passenger passenger){
	     Double discountPrice=0d;
	     if(null!=passenger.getFeePrice()){
	    	 discountPrice=Double.valueOf(passenger.getFeePrice());
	     }
		 Double viewPrice=Double.valueOf(passenger.getTicketPtice());
//		 Double constructionFee=passengerDto.getConstructionFee()+passenger.getConstructionFee();
//		 Double fuelTax=passengerDto.getFuelTax()+passenger.getFuelTax();
		 Double constructionFee=Double.valueOf(passenger.getConstructionFee());
		 Double fuelTax=Double.valueOf(passenger.getFuelTax());
		 Integer passengerCount=passengerDto.getPassengerCount()+1;
		 Long bxPrice=passenger.getBxPrice();
		 Long bxCount=0l;
		 if(passenger.getInsuranceCount()>0){
			 bxCount= passengerDto.getBxCount()+1;
		 }
		 Double allTotalPrice=viewPrice+constructionFee+fuelTax+bxPrice*passenger.getInsuranceCount();
	/*	 if(passenger.getInsuranceCount()>0){
			 allTotalPrice+=-passenger.getbOrder().getInsuranceCuttingPrice();
		 }*/
		 Double totalPrice=passengerDto.getTotalPrice()+allTotalPrice;
		 
		 passengerDto.setBxCount(bxCount);
		 passengerDto.setBxPrice(bxPrice);
		 passengerDto.setConstructionFee(constructionFee);
		 passengerDto.setDiscountPrice(discountPrice);
		 passengerDto.setFuelTax(fuelTax);
		 passengerDto.setPassengerCount(passengerCount);
		 passengerDto.setTotalPrice(totalPrice);
		 passengerDto.setViewPrice(viewPrice);
		 
		 return passengerDto;
	}

	@Override
	public Boolean saveByOrderNo(String orderNo, String payPrice) {
		
			BOrder bOrder= this.findOrderByNo(orderNo);
			payPrice="1";	
			bOrder.setPayChannel("支付宝");
			bOrder.setStatus(BOrderCommon.getOrderStatusMap().get(
					OrderStatus.PAY_OK));
			bOrder.setNoPay(bOrder.getNoPay()-Long.valueOf(payPrice));
			bOrder.setTradeNo(orderNo);
			try{
			this.save(bOrder);}catch (Exception e) {
				return false;
			}
			return true;
	}

}
